﻿using System;
using System.ComponentModel;
using System.Configuration;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Web;

namespace SubjectWorkShop.Core
{
    public class SubjectSettings
    {
        //============================================================
        //	PUBLIC/PRIVATE/PROTECTED MEMBERS
        //============================================================
        #region PRIVATE/PROTECTED/PUBLIC MEMBERS

        public static event EventHandler<EventArgs> Changed;
        private static SubjectSettings subjectSettingsSingleton;
        private string configuredTheme = "Standard";
        bool enableHttpCompression;

        #endregion


        
		//============================================================
		//	CONSTRUCTORS
		//============================================================
		#region SubjectSetting()
		/// <summary>
		/// Initializes a new instance of the <see cref="BlogSettings"/> class.
		/// </summary>
        private SubjectSettings()
		{
			//------------------------------------------------------------
			//	Attempt to initialize class state
			//------------------------------------------------------------
			//try
			//{
			//------------------------------------------------------------
			//	Load the currently configured settings
			//------------------------------------------------------------
			Load();
			//}
			//catch
			//{
			//    //------------------------------------------------------------
			//    //	Rethrow exception
			//    //------------------------------------------------------------
			//    throw;
			//}
		}
		#endregion



        //============================================================
        //	STATIC PROPERTIES
        //============================================================
        #region Instance
        /// <summary>
        /// Gets the singleton instance of the <see cref="BlogSettings"/> class.
        /// </summary>
        /// <value>A singleton instance of the <see cref="BlogSettings"/> class.</value>
        /// <remarks></remarks>
        public static SubjectSettings Instance
        {
            get
            {
                if (subjectSettingsSingleton == null)
                {
                    subjectSettingsSingleton = new SubjectSettings();
                }
                return subjectSettingsSingleton;
            }
        }
        #endregion


        //============================================================
        //	PRIVATE ROUTINES
        //============================================================
        #region Load()
        /// <summary>
        /// Initializes the singleton instance of the <see cref="BlogSettings"/> class.
        /// </summary>
        private void Load()
        {
            Type settingsType = this.GetType();

            //------------------------------------------------------------
            //	Enumerate through individual settings nodes
            //------------------------------------------------------------
            System.Collections.Specialized.StringDictionary dic = Providers.SubjectService.LoadSettings();

            foreach (string key in dic.Keys)
            {
                //------------------------------------------------------------
                //	Extract the setting's name/value pair
                //------------------------------------------------------------
                string name = key;
                string value = dic[key];

                //------------------------------------------------------------
                //	Enumerate through public properties of this instance
                //------------------------------------------------------------
                foreach (PropertyInfo propertyInformation in settingsType.GetProperties())
                {
                    //------------------------------------------------------------
                    //	Determine if configured setting matches current setting based on name
                    //------------------------------------------------------------
                    if (propertyInformation.Name.Equals(name, StringComparison.OrdinalIgnoreCase))
                    {
                        //------------------------------------------------------------
                        //	Attempt to apply configured setting
                        //------------------------------------------------------------
                        try
                        {
                            if (propertyInformation.CanWrite)
                            {
                                propertyInformation.SetValue(this, Convert.ChangeType(value, propertyInformation.PropertyType, CultureInfo.CurrentCulture), null);
                            }
                        }
                        catch
                        {
                            // TODO: Log exception to a common logging framework?
                        }
                        break;
                    }
                }
            }
            StorageLocation = Providers.SubjectService.GetStorageLocation();
        }
        #endregion


        #region StorageLocation
        /// <summary>
        /// Gets or sets the default storage location for blog data.
        /// </summary>
        /// <value>The default storage location for blog data.</value>
        public string StorageLocation { get; set; }
        #endregion

        #region Timezone
        /// <summary>
        /// Gets or sets the maximum number of characters that are displayed from a blog-roll retrieved post.
        /// </summary>
        /// <value>The maximum number of characters to display.</value>
        public double Timezone { get; set; }
        #endregion

        #region HandleWwwSubdomain
        /// <summary>
        /// Gets or sets how to handle the www subdomain of the url (for SEO purposes).
        /// </summary>
        public string HandleWwwSubdomain { get; set; }
        #endregion

        #region FileExtension
        /// <summary>
        /// The  file extension used for aspx pages
        /// </summary>
        public string FileExtension
        {
            get { return ConfigurationManager.AppSettings["SujbectWS.FileExtension"] ?? ".aspx"; }
        }
        #endregion

        #region AlternateFeedUrl
        /// <summary>Gets or sets the FeedBurner user name.</summary>
        public string AlternateFeedUrl { get; set; }
        #endregion

        #region TimeStampPostLinks
        /// <summary>Gets or sets whether or not to time stamp post links.</summary>
        public bool TimeStampPostLinks { get; set; }
        #endregion

        #region EnableHttpCompression
        /// <summary>
        /// Gets or sets a value indicating if HTTP compression is enabled.
        /// </summary>
        /// <value><b>true</b> if compression is enabled, otherwise returns <b>false</b>.</value>
        public bool EnableHttpCompression { get; set; }
        #endregion

        #region CompressWebResource
        /// <summary>
        /// Gets or sets a value indicating whether to compress WebResource.axd
        /// </summary>
        /// <value><c>true</c> if [compress web resource]; otherwise, <c>false</c>.</value>
        public bool CompressWebResource { get; set; }
        #endregion

        #region EnableReferrerTracking
        /// <summary>
        /// Gets or sets a value indicating if referral tracking is enabled.
        /// </summary>
        /// <value><b>true</b> if referral tracking is enabled, otherwise returns <b>false</b>.</value>
        public bool EnableReferrerTracking { get; set; }
        #endregion

        #region Theme
        /// <summary>
        /// Gets or sets the current theme applied to the blog.
        /// </summary>
        /// <value>The configured theme for the blog.</value>
        public string Theme
        {
            get
            {
                return configuredTheme;
            }

            set
            {
                if (String.IsNullOrEmpty(value))
                {
                    configuredTheme = String.Empty;
                }
                else
                {
                    configuredTheme = value;
                }
            }
        }
        #endregion

        #region EnableOpenSearch
        /// <summary>
        /// Gets or sets a value indicating if whitespace in stylesheets should be removed
        /// </summary>
        /// <value><b>true</b> if whitespace is removed, otherwise returns <b>false</b>.</value>
        public bool EnableOpenSearch { get; set; }
        #endregion

        #region HtmlHeader
        /// <summary>
        /// Gets or sets the name of the author of this blog.
        /// </summary>
        /// <value>The name of the author of this blog.</value>
        public string HtmlHeader { get; set; }
        #endregion

        #region TrackingScript
        /// <summary>
        /// Gets or sets the tracking script used to collect visitor data.
        /// </summary>
        public string TrackingScript { get; set; }
        #endregion

        #region AdministratorRole
        /// <summary>
        /// The role that has administrator persmissions
        /// </summary>
        public string AdministratorRole
        {
            get { return ConfigurationManager.AppSettings["BlogEngine.AdminRole"] ?? "administrators"; }
        }
        #endregion

        #region RemoveWhitespaceInStyleSheets
        /// <summary>
        /// Gets or sets a value indicating if whitespace in stylesheets should be removed
        /// </summary>
        /// <value><b>true</b> if whitespace is removed, otherwise returns <b>false</b>.</value>
        public bool RemoveWhitespaceInStyleSheets { get; set; }
        #endregion

        #region Name
        /// <summary>
        /// Gets or sets the name of the website.
        /// </summary>
        /// <value>The title of the blog.</value>
        public string Name { get; set; }
        #endregion

        #region Version()

        private static string _Version;
        /// <summary>
        /// Returns the BlogEngine.NET version information.
        /// </summary>
        /// <value>The BlogEngine.NET major, minor, revision, and build numbers.</value>
        /// <remarks>The current version is determined by extracting the build version of the BlogEngine.Core assembly.</remarks>
        public string Version()
        {
            if (_Version == null)
                _Version = GetType().Assembly.GetName().Version.ToString();         //..g

            return _Version;
        }
        #endregion

        #region Culture
        /// <summary>
        /// Gets or sets the name of the author of this blog.
        /// </summary>
        /// <value>The name of the author of this blog.</value>
        public string Culture { get; set; }
        #endregion


        #region Transformlocation
        /// <summary>
        /// Gets or sets the name of the author of this blog.
        /// </summary>
        /// <value>The name of the author of this blog.</value>
        public string Transformlocation { get; set; }
        #endregion
                  
    }
}
